
#################################################################################
# Perform-Deployment - Deployment Starts Here and Ends Here
#################################################################################
function Perform-Deployment
{
  $Env = Get-Env $TargetEnv

  if (ShowingHelp) {return}

  if ($all)
  {
    if ($verbose)
    {
      Show-Env $Env
    }
    if ($PerformDeploy)#consider adding conditional check to validate if services are configured before displaying
    {
      Log-Message $MajorLine
    } 
    check-Access
		ReTry "Initiating App_offline" {App-offline Stop} -AllowSkip
    ReTry "Stopping Websites" {Manage-WebSites Stop} -AllowSkip
    ReTry "Stopping WinServices" {Manage-WinServices Stop} -AllowSkip
    ReTry "Stopping AppPools" {Manage-AppPools Stop} -AllowSkip
    
    if ($PerformDeploy)
    {
      Log-Message $MajorLine
      Log-Message "All Applications in $($Env.Name)"
    }
    Deploy-AllApplicationsInEnvironment 
    if ($PerformDeploy)
    {
      Log-Message $MajorLine
    }
		ReTry "Removing App_offline" {App-offline Start} -AllowSkip
    ReTry "Starting Websites" {Manage-WebSites Start} -AllowSkip
    ReTry "Starting WinServices" {Manage-WinServices Start} -AllowSkip
    ReTry "Starting AppPools" {Manage-AppPools Start} -AllowSkip
		ReTry "Recycle IIS" {Recycle-IIS}  -AllowSkip
	
  }
  elseif ( $TargetServer -ne "all" -and $TargetApp -ne "all" )
  {
    $server = Get-Server $TargetServer
    $app = Get-App $server $TargetApp
    ReTry "Deploying  $TargetApp on $TargetServer" {
    Deploy-ApplicationOnServer $server $app
	}
  }
  elseif ( $TargetServer -eq "all" -and $TargetApp -ne "all" )
  {
    if (($custApp = Get-CustomApp $TargetEnv $TargetApp) -ne $null)
    {
      $custAppEnv = $custApp.environments[$TargetEnv]
      Log-Message "Deploying Custom Application $($custApp.Name) to $($custAppEnv.name)"
      ReTry "Deploying Custom Application $($custApp.Name) to $custAppEnv" {
				Deploy-CustomApplication $custApp.Name $custAppEnv
	  	} #-ShowStatus
    }
    elseif (($dbDeployment = Get-dbDeployment $TargetEnv $TargetApp) -ne $null)
    {
      $dbDeploymentEnv = $dbDeployment.environments[$TargetEnv]
      Log-Message "Deploying Database $($dbDeployment.Name) to $TargetEnv"
      ReTry "Deploying Database $($dbDeployment.Name) to $TargetEnv" {
				Deploy-Database -Env $TargetEnv -ConfigFile $($dbDeployment.config) -Whatif:$Whatif
	  	} #-ShowStatus
    }
    else
    {
      ReTry "Deploying $TargetApp Application on All Servers" {
      	Deploy-ApplicationOnAllServers $TargetApp
	  	} #-ShowStatus
    }
  }
  elseif ( $TargetServer -ne "all" -and $TargetApp -eq "all")
  {
    $server = Get-Server $TargetServer
    ReTry "Deploying $Deploy All Applications on $server" {
    Deploy-AllApplicationsOnServer $server
	  } #-ShowStatus
  }
  else
  {
    Show-ScriptUsage
  }
    if (!$Whatif)
    {  
      Log-Message $MajorLine -foregroundcolor green
      Log-Message "============================== DEPLOYMENT COMPLETED ==========================================" -foregroundcolor green
      Log-Message $MajorLine -foregroundcolor green  
    }
    else
    {
      Log-Message $MajorLine
      Log-Message "To execute this deployment add -execute to the commandline" -foregroundcolor yellow
      Log-Message "Example: ./deploy -TargetEnv dev -execute" -foregroundcolor yellow
  	}
}

#################################################################################
## Deploy app on a server - start/stop websites and services
#################################################################################

function Deploy-ApplicationOnServer
{
  param( $server, $app )
  $root = Get-RootFolder
  $WinService = Get-WinServiceForApp $app
  $WebSite = Get-WebSiteForApp $app 
  $AppPool = Get-AppPoolForApp $app
  $servername = $server.FQname
  
  ## This handles ClusterServices if they exist
  foreach ($application in $server.Applications)
  {
    
    foreach ($clusterservice in $app.EnvServices)
    { 
      if ($clusterservice.ClusterName.length -gt 0 -and $clusterservice.env -eq $Env.Name)
      {
        $servername = $clusterservice.ClusterName
      }
    }
  }
  Log-Message $MinorLine
  Log-Message $app.Name
  Log-Message $MinorLine

  if (!($all))   
  {
    ReTry "Stop Services on $serverName" {
    Stop-ServicesOnServer -serviceName $WinService -serverName $serverName -webSite $WebSite -AppPool $AppPool
    } -AllowSkip #-ShowStatus
  }
  if ($PerformDeploy)
  {
    Delete-ApplicationFiles $server $app
    Copy-ApplicationFiles $server $app
  }
  
  if (!($all))   
  {
    ReTry "Start Services on $serverName" {
    Start-ServicesOnServer -serviceName $WinService -serverName $serverName -webSite $WebSite -AppPool $AppPool
    } -AllowSkip #-ShowStatus
  }
}

#################################################################################
function Deploy-ApplicationOnAllServers 
{
  param( $TargetApp )

  foreach( $server in $Env.Servers )
  {
    foreach ( $app in $server.Applications )
    {
      if ($app.Name -eq $TargetApp)
      {
        ReTry "Deploy $($app.Name) on $($server.Name)" {
        Deploy-ApplicationOnServer $server $app 
        } -AllowSkip #-ShowStatus
      }
    }	
  }
}
#################################################################################
function Deploy-AllApplicationsOnServer
{
  param( $server )
  
  foreach( $app in $server.Applications )
  {
    ReTry "Deploy $($app.Name)" {
    Deploy-ApplicationOnServer $server $app 
    } -AllowSkip #-ShowStatus
  }
}

#################################################################################
function Deploy-AllApplicationsInEnvironment
{ 
  foreach( $custApp in $Global:custApps )
  {
    $custAppEnv = $custApp.environments[$env.name]
		if ($custAppEnv.name -eq $TargetEnv)
		{
			ReTry "Deploy $($custApp.Name)" {
			Deploy-CustomApplication $custApp.Name $custAppEnv
			} -AllowSkip #-ShowStatus
		}
  }
  
	foreach( $dbDeployment in $Global:dbDeployments )
  {
    $dbDeploymentEnv = $dbDeployment.environments[$env.name]
		if ($dbDeploymentEnv.name -eq $TargetEnv)
		{
			ReTry "Deploy $($custApp.Name)" {
				Deploy-Database -Env $TargetEnv -ConfigFile $($dbDeployment.config) -Whatif:$Whatif
			} -AllowSkip #-ShowStatus
		}
  }
	
	foreach( $server in $Env.Servers )
  {
    ReTry "Deploy all Applications on $($server.Name)" {
    Deploy-AllApplicationsOnServer $server
    } -AllowSkip #-ShowStatus
  }
}